Skip to content

OLS-3450: Add credentialHotReload flag to skip app-server restart on LLM secret rotation - #1779

Merged
openshift-merge-bot[bot] merged 1 commit into
openshift:mainfrom
lalan7:feat/credential-hot-reload
Sep 30, 2026
Merged

openshift-merge-bot[bot] merged 1 commit into
openshift:mainfrom
lalan7:feat/credential-hot-reload

Conversation

@lalan7

@lalan7 lalan7 commented Jul 2, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Adds opt-in credentialHotReload boolean to OLSSpec CRD (default: false)
  • When enabled, the operator's secret watcher skips rolling restart for LLM credential secrets — the service re-reads credentials from disk on each request (RFE-9380)
  • Preserves existing behavior for all clusters when disabled

Test plan

  • Unit tests: 3 new tests covering skip/no-skip/non-LLM paths (23/23 pass)
  • E2e test: rotate LLM secret with flag enabled, verify no restart via Consistently
  • go vet ./... clean
  • go build ./... clean
  • CRD regenerated via make manifests

Related

Summary by CodeRabbit

  • New Features
    • Added spec.ols.credentialHotReload to reload rotated LLM credentials without app-server restarts.
    • When enabled, supported services automatically read updated credential data.
  • Documentation
    • Added guidance on prerequisites and behavior for credential data and secret reference changes.
  • Tests
    • Added coverage verifying hot-reload configuration and watcher behavior when enabled or disabled.

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Jul 2, 2026
@openshift-ci-robot

openshift-ci-robot commented Jul 2, 2026 •

Copy link
Copy Markdown

@lalan7: This pull request references OLS-3450 which is a valid jira issue.

Details

In response to this:

Summary

  • Adds opt-in credentialHotReload boolean to OLSSpec CRD (default: false)
  • When enabled, the operator's secret watcher skips rolling restart for LLM credential secrets — the service re-reads credentials from disk on each request (RFE-9380)
  • Preserves existing behavior for all clusters when disabled

Test plan

  • Unit tests: 3 new tests covering skip/no-skip/non-LLM paths (23/23 pass)
  • E2e test: rotate LLM secret with flag enabled, verify no restart via Consistently
  • go vet ./... clean
  • go build ./... clean
  • CRD regenerated via make manifests

Related

Made with Cursor

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@coderabbitai

coderabbitai Bot commented Jul 2, 2026 •

Copy link
Copy Markdown

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds an optional CredentialHotReload setting to OLSConfig, propagates it to app-server configuration, removes LLM provider secret watcher annotations when enabled, and validates the behavior with tests and documentation.

Changes

Credential Hot-Reload

Layer / File(s) Summary
Configuration and app-server propagation
api/v1alpha1/olsconfig_types.go, internal/controller/utils/types.go, internal/controller/appserver/assets.go, internal/controller/olsconfig_controller.go
Adds API and internal configuration fields, generates credential_hot_reload, and logs when hot-reload is enabled.
LLM secret watcher control
internal/controller/olsconfig_helpers.go, internal/controller/watchers/watchers.go, internal/controller/watchers/watchers_test.go
Removes watcher annotations from LLM provider secrets when enabled while preserving existing handling for other resources.
Behavior validation and documentation
internal/controller/olsconfig_helpers_test.go, test/e2e/reconciliation_test.go, docs/credential-hot-reload.md
Tests annotation removal and restoration, verifies generated configuration end to end, and documents secret handling and prerequisites.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant OLSConfig
  participant OLSConfigReconciler
  participant LLMSecret
  participant AppServerConfig
  participant SecretWatcherFilter
  participant AppServerDeployment

  OLSConfig->>OLSConfigReconciler: provide CredentialHotReload
  OLSConfigReconciler->>AppServerConfig: set credential_hot_reload
  OLSConfigReconciler->>LLMSecret: remove watcher annotation
  LLMSecret-->>SecretWatcherFilter: credential secret event
  alt hot-reload enabled
    SecretWatcherFilter-->>AppServerDeployment: no restart trigger
  else hot-reload disabled
    SecretWatcherFilter->>AppServerDeployment: trigger restart
  end
Loading

Suggested reviewers: bparees, xrajesh

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the primary change: adding a credentialHotReload flag to skip app-server restart on LLM secret rotation, which directly aligns with the main functionality implemented across CRD, controller, and e2e test changes.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@openshift-ci
openshift-ci Bot requested review from bparees and xrajesh July 2, 2026 20:34

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
internal/controller/watchers/watchers_test.go (1)

363-471: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider extracting the repeated Deployment/reconciler setup into a helper.

The three new tests duplicate identical dep/createTestReconciler boilerplate. A small local helper (e.g., newTestDeploymentAndReconciler(cr)) would reduce repetition within this file.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/controller/watchers/watchers_test.go` around lines 363 - 471, The
new Credential hot-reload tests duplicate the same Deployment and reconciler
setup in each case. Extract that repeated boilerplate into a small local helper
in watchers_test.go, such as a helper that builds the standard Deployment and
calls createTestReconciler, then reuse it in the three Describe/It blocks while
keeping the test-specific watcher config and Secret setup inline.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/controller/utils/types.go`:
- Around line 60-73: `WatcherConfig` is shared mutable state and is accessed
concurrently by `SecretWatcherFilter()` while `annotateExternalResources()`
updates `CredentialHotReload` and `LLMSecretNames`; add synchronization or
switch to an immutable snapshot approach. Update the `WatcherConfig` type in
`types.go` to guard these fields with a mutex (or refactor to store/retrieve a
copied config atomically), and make both `SecretWatcherFilter()` and
`annotateExternalResources()` use the same protection when reading or writing
`CredentialHotReload` and `LLMSecretNames`.

In `@test/e2e/reconciliation_test.go`:
- Around line 400-416: The reconciliation test uses a fixed sleep after updating
OLSConfig.CredentialHotReload, which makes the hot-reload setup timing-dependent
and flaky. Replace the blind time.Sleep in the credentialHotReload setup with an
Eventually-based wait on an observable signal from the reconciler, such as a
status condition, annotation, or other field updated when the latest
spec.generation has been processed. Use the existing client.Update, client.Get,
and deployment.Generation flow to locate the test, and keep the later
Consistently assertion only after the reconciler-ready signal is observed.

---

Nitpick comments:
In `@internal/controller/watchers/watchers_test.go`:
- Around line 363-471: The new Credential hot-reload tests duplicate the same
Deployment and reconciler setup in each case. Extract that repeated boilerplate
into a small local helper in watchers_test.go, such as a helper that builds the
standard Deployment and calls createTestReconciler, then reuse it in the three
Describe/It blocks while keeping the test-specific watcher config and Secret
setup inline.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: b0d1bbf1-2bfc-49b1-a705-c12229c81079

📥 Commits

Reviewing files that changed from the base of the PR and between 7ed4504 and b59c74c.

⛔ Files ignored due to path filters (1)
  • config/crd/bases/ols.openshift.io_olsconfigs.yaml is excluded by !config/crd/bases/**
📒 Files selected for processing (8)
  • api/v1alpha1/olsconfig_types.go
  • docs/credential-hot-reload.md
  • internal/controller/olsconfig_controller.go
  • internal/controller/olsconfig_helpers.go
  • internal/controller/utils/types.go
  • internal/controller/watchers/watchers.go
  • internal/controller/watchers/watchers_test.go
  • test/e2e/reconciliation_test.go

Comment thread internal/controller/utils/types.go
Comment thread test/e2e/reconciliation_test.go Outdated
@lalan7

lalan7 commented Jul 7, 2026 •

Copy link
Copy Markdown
Contributor Author

Hi @blublinsky — this is the operator companion to service PR openshift/lightspeed-service#2955 (RFE-9380).

Adds an opt-in credentialHotReload boolean to the OLSConfig CRD. When enabled, the operator skips rolling restarts for LLM credential secret rotations — the service handles it in-process. Default is false, so no behavior change for existing clusters.

All CI checks pass. The bundle-e2e-4-21 failure is a pre-existing main issue (unknown fields agenticConsole/alertsAdapter in test fixtures from PRs #1758/#1759), not related to this change.

Would appreciate a review when you have a chance.

@blublinsky

Copy link
Copy Markdown
Contributor

Suggestion: drive hot-reload from ForEachExternalSecret instead of SecretWatcherFilter

The flag is currently wired in two places: LLMSecretNames + CredentialHotReload are populated before ForEachExternalSecret, and SecretWatcherFilter has a runtime skip branch. That duplicates the provider iteration and adds special-case logic on the event path.

A simpler approach is to handle this inside the ForEachExternalSecret callback, the same way TLS secrets get their AnnotatedSecretMapping today: when credentialHotReload is enabled and source is llm-provider-*, do not annotate that secret (skip annotateSecretIfNeeded). Without the watcher annotation, shouldWatchSecret never admits it, so no restart watcher is created for that secret — no .data events on the hot-reload path, no SecretWatcherFilter changes, no LLMSecretNames map, no extra fields on WatcherConfig, no skip logic at event time.

When the flag is off, behavior stays as today: foreach annotates LLM credential secrets and rotations trigger a rolling restart as they do now.

That keeps “which secrets does the operator react to?” entirely in the existing foreach/mapping configuration model, instead of splitting it between reconcile-time config and filter-time exceptions.

One thing to nail when toggling the flag on for clusters that already have annotated LLM secrets: reconcile may need to remove the watcher annotation when hot-reload is enabled, not only skip adding it for new ones.


I’d hold off on deeper review until this is reworked — the foreach-based approach removes most of the PR’s watcher-layer changes and is the pattern we already use for other secret types.

@blublinsky

Copy link
Copy Markdown
Contributor

Follow-up: credentialHotReload must reach the service via OLS config for end-to-end behavior

Today this flag lives only on the CR and in operator WatcherConfig (skip restart). It is not propagated into the app-server olsconfig ConfigMap (buildOLSConfig / AppSrvConfigFile) and the service PR has no corresponding config field either.

That leaves two independent behaviors with no runtime coupling:

Layer What happens
Operator (credentialHotReload: true) Skips pod restart on LLM secret rotation
Service (lightspeed-service #2955) Re-reads credentials_path on every request — but unconditionally, not driven by this flag

For this to work end-to-end, the flag should flow:

OLSConfig CR (spec.ols.credentialHotReload)
  → operator builds olsconfig ConfigMap
  → service reads config and enables hot-reload credential reads when true

Without that, enabling the CR flag on a cluster with an older service image (or before #2955 is deployed) silently disables restarts while credentials stay stale at startup — the CR comment warns about this, but nothing in config enforces it.

Suggest:

  1. Add the field to the generated OLS config (utils.OLSConfig / buildOLSConfig).
  2. Service side: gate get_credentials() disk re-read on that config flag (default false for backward compatibility).
  3. Operator watcher skip (ideally via ForEachExternalSecret / no annotation) should follow the same CR flag.

That gives one user-facing switch that coordinates both “don’t restart” and “do re-read from disk,” instead of two repos assuming the other half is always correct.

@blublinsky

Copy link
Copy Markdown
Contributor

Scoping: operator-only PR + bundle follow-up

This PR is correctly scoped to the operator only — service changes stay in openshift/lightspeed-service#2955. Keep it that way.

Once the operator changes here are in good shape, suggest landing this PR without blocking on the OLM bundle, then a follow-up PR that runs make manifests && make bundle (or hack/update_bundle.sh) so bundle/manifests/ols.openshift.io_olsconfigs.yaml picks up credentialHotReload. Right now the field is only in config/crd/bases/; OLM installs use the bundle CRD, so the feature isn’t usable from the shipped bundle until that follow-up.

Order I’d expect:

  1. Operator PR (this repo) — CRD + reconcile/watcher wiring + config pass-through to olsconfig once agreed
  2. Service PR — gated get_credentials() re-read on config flag
  3. Bundle follow-up — regenerate committed bundle/ manifests

That keeps review focused and matches how we usually ship CRD schema vs bundle image updates.

@openshift-ci openshift-ci Bot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jul 14, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/controller/olsconfig_helpers.go`:
- Around line 389-416: The credential hot-reload branch in the
ForEachExternalSecret callback currently logs failures from
removeSecretAnnotationIfNeeded without recording them. Append that error to errs
before returning, matching the existing annotateSecretIfNeeded error handling so
reconciliation reports the failure and retries.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 6896947a-047f-45c2-a404-05c4b75468c8

📥 Commits

Reviewing files that changed from the base of the PR and between b59c74c and 1eaa6a2.

📒 Files selected for processing (6)
  • internal/controller/appserver/assets.go
  • internal/controller/olsconfig_helpers.go
  • internal/controller/utils/types.go
  • internal/controller/watchers/watchers.go
  • internal/controller/watchers/watchers_test.go
  • test/e2e/reconciliation_test.go
💤 Files with no reviewable changes (2)
  • internal/controller/watchers/watchers.go
  • internal/controller/watchers/watchers_test.go

Comment thread internal/controller/olsconfig_helpers.go
@lalan7
lalan7 force-pushed the feat/credential-hot-reload branch from 1eaa6a2 to 1cda906 Compare July 14, 2026 14:51
@openshift-ci openshift-ci Bot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jul 14, 2026
@lalan7

lalan7 commented Jul 14, 2026

Copy link
Copy Markdown
Contributor Author

@blublinsky

Addressed all code review findings in the latest push:

Service (lightspeed-service):

Consolidated AWS credential reads — Bedrock.load() now calls get_aws_credentials() once and passes the tuple through to _build_boto3_session() / _build_sigv4_auth() via an optional parameter. This cuts disk reads per load() from 6 to 3 and eliminates a potential mid-request partial rotation race (e.g. new access_key + old secret_key if rotation lands between calls).

Guarded optional role_arn read — get_aws_credentials() now checks os.path.isfile() before attempting to read the role_arn file, avoiding spurious warning logs when it's not configured (common scenario).

Operator (lightspeed-operator):

Collected removeSecretAnnotationIfNeeded errors — failures are now appended to the errs slice, consistent with annotateSecretIfNeeded error handling. Previously these were logged but silently swallowed.
Replaced hardcoded annotation key in e2e test — all 3 instances of "ols.openshift.io/watcher" now use utils.WatcherAnnotationKey.

Added unit tests for removeSecretAnnotationIfNeeded — covers annotation present (removed), annotation absent (no-op), and secret not found (no-op).

All service tests pass (28/28). Operator compiles and passes go vet cleanly (envtest unit tests require kubebuilder binaries available only in CI).

@lalan7

lalan7 commented Jul 14, 2026

Copy link
Copy Markdown
Contributor Author

/retest

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/controller/olsconfig_helpers.go`:
- Around line 408-413: Protect shared WatcherConfig map access with one
sync.RWMutex: guard the AnnotatedSecretMapping write in
internal/controller/olsconfig_helpers.go lines 408-413 and the
AnnotatedConfigMapMapping write in lines 440-442, and use the same mutex in
SecretWatcherFilter and ConfigMapWatcherFilter for corresponding reads.
- Around line 454-458: Update the error-return path in the helper containing the
errs check so non-empty errs is aggregated and returned instead of returning
nil, ensuring reconciliation retries. Use r.GetLogger().Info for the retry
message, and wrap the aggregated error with fmt.Errorf using the applicable
shared error constant from internal/controller/utils/errors.go. Preserve the
existing successful nil return when errs is empty.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 7d5c034e-00f0-4ca2-b7e6-6f8776b361d0

📥 Commits

Reviewing files that changed from the base of the PR and between 1eaa6a2 and ee29f5d.

⛔ Files ignored due to path filters (2)
  • bundle/manifests/ols.openshift.io_olsconfigs.yaml is excluded by !bundle/manifests/ols.openshift.io_olsconfigs.yaml
  • config/crd/bases/ols.openshift.io_olsconfigs.yaml is excluded by !config/crd/bases/**
📒 Files selected for processing (10)
  • api/v1alpha1/olsconfig_types.go
  • docs/credential-hot-reload.md
  • internal/controller/appserver/assets.go
  • internal/controller/olsconfig_controller.go
  • internal/controller/olsconfig_helpers.go
  • internal/controller/olsconfig_helpers_test.go
  • internal/controller/utils/types.go
  • internal/controller/watchers/watchers.go
  • internal/controller/watchers/watchers_test.go
  • test/e2e/reconciliation_test.go
🚧 Files skipped from review as they are similar to previous changes (8)
  • internal/controller/watchers/watchers.go
  • internal/controller/watchers/watchers_test.go
  • api/v1alpha1/olsconfig_types.go
  • test/e2e/reconciliation_test.go
  • internal/controller/appserver/assets.go
  • internal/controller/olsconfig_controller.go
  • docs/credential-hot-reload.md
  • internal/controller/utils/types.go

Comment on lines 408 to 413
if r.WatcherConfig != nil && source == "tls" {
r.WatcherConfig.AnnotatedSecretMapping[name] = []string{
utils.ConsoleUIDeploymentName,
"ACTIVE_BACKEND",
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🔴 Critical | 🏗️ Heavy lift

Concurrent map read/write data race on r.WatcherConfig.

Both map writes in the reconciler loop cause a fatal data race with concurrent reads from the informer event handlers (SecretWatcherFilter and ConfigMapWatcherFilter). Maps in Go are not thread-safe, and this overlap will crash the operator with a panic. The shared root cause is a lack of synchronization when accessing WatcherConfig state across distinct execution threads.

  • internal/controller/olsconfig_helpers.go#L408-L413: guard writes to r.WatcherConfig.AnnotatedSecretMapping with a sync.RWMutex.
  • internal/controller/olsconfig_helpers.go#L440-L442: guard writes to r.WatcherConfig.AnnotatedConfigMapMapping with the same mutex.
📍 Affects 1 file
  • internal/controller/olsconfig_helpers.go#L408-L413 (this comment)
  • internal/controller/olsconfig_helpers.go#L440-L442
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/controller/olsconfig_helpers.go` around lines 408 - 413, Protect
shared WatcherConfig map access with one sync.RWMutex: guard the
AnnotatedSecretMapping write in internal/controller/olsconfig_helpers.go lines
408-413 and the AnnotatedConfigMapMapping write in lines 440-442, and use the
same mutex in SecretWatcherFilter and ConfigMapWatcherFilter for corresponding
reads.

Comment thread internal/controller/olsconfig_helpers.go

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
internal/controller/olsconfig_helpers.go (1)

419-426: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Use the required reconciler logger.

Replace r.Logger.Error with r.GetLogger().Error in both error paths to follow the repository’s mandated logging pattern.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/controller/olsconfig_helpers.go` around lines 419 - 426, Replace
r.Logger.Error with r.GetLogger().Error in both error paths within the secret
annotation/removal flow, including the calls for “Failed to remove annotation
from secret” and “Failed to annotate secret,” while preserving their existing
arguments.

Sources: Coding guidelines, Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@internal/controller/olsconfig_helpers.go`:
- Around line 419-426: Replace r.Logger.Error with r.GetLogger().Error in both
error paths within the secret annotation/removal flow, including the calls for
“Failed to remove annotation from secret” and “Failed to annotate secret,” while
preserving their existing arguments.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 7a81df0a-1ec3-449f-91ee-c57671646807

📥 Commits

Reviewing files that changed from the base of the PR and between ee29f5d and 3848992.

📒 Files selected for processing (2)
  • internal/controller/olsconfig_helpers.go
  • test/e2e/reconciliation_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/e2e/reconciliation_test.go

@lalan7

lalan7 commented Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

/retest

1 similar comment
@lalan7

lalan7 commented Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

/retest

@raptorsun

Copy link
Copy Markdown
Contributor

we are going to have a discussion reviewing the design of this feature and then decide how to proceed.

@openshift-ci openshift-ci Bot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Aug 3, 2026
@lalan7
lalan7 force-pushed the feat/credential-hot-reload branch from 3848992 to 3310923 Compare August 4, 2026 13:21
@openshift-ci openshift-ci Bot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Aug 4, 2026
@lalan7

lalan7 commented Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

/retest

2 similar comments
@lalan7

lalan7 commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

/retest

@lalan7

lalan7 commented Aug 10, 2026

Copy link
Copy Markdown
Contributor Author

/retest

@lalan7

lalan7 commented Aug 10, 2026

Copy link
Copy Markdown
Contributor Author

@raptorsun — thanks for the heads up. Happy to join the design discussion or provide any additional context on the approach. Just to summarize where things stand:

I implemented all of @blublinsky's feedback (annotation-based approach via ForEachExternalSecret, ConfigMap propagation to the service, gated get_credentials() on the flag)
All Prow CI checks are green on both PRs (operator #1779 + service #2955)
The feature is opt-in (credentialHotReload: false by default), no behavior change for existing clusters
Please let me know when the discussion is scheduled — I'd like to be there to answer any questions. Thanks!

@blublinsky

Copy link
Copy Markdown
Contributor

should-fix: "How It Works" section describes the old watcher-filter approach, not the current annotation-based implementation

docs/credential-hot-reload.md lines 44–52 still describe the original approach (commit 1) where the flag was stored in WatcherConfig and the watcher filter had skip logic. The reworked approach (commit 2) is entirely different — the operator removes the watcher annotation from LLM secrets, so the watcher predicate never admits the event.

Suggested rewrite for "How It Works":

  1. During reconciliation, if credentialHotReload is enabled and the secret source is llm-provider-*, the operator removes the watcher annotation (or skips adding it for new secrets).
  2. Without the annotation, the watcher predicate (shouldWatchSecret) does not admit the event — no restart happens.
  3. When the flag is toggled off, the annotation is re-added on the next reconciliation, restoring restart behavior.
  4. Non-LLM secrets (TLS, MCP, Postgres) are annotated and trigger restarts regardless of the flag.

@blublinsky

Copy link
Copy Markdown
Contributor

should-fix: Squash commits before merge

The PR has 6 commits including incremental review fixes and a revert (commit 5 is reverted by commit 6). Per repo conventions, please squash to a single logical commit before merge.

@lalan7
lalan7 force-pushed the feat/credential-hot-reload branch from 241bf1f to 0b76bd0 Compare September 18, 2026 19:27
@openshift-ci openshift-ci Bot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Sep 18, 2026
@blublinsky

Copy link
Copy Markdown
Contributor

Please regenerate the generated manifests using make manifests and make bundle.

@lalan7
lalan7 force-pushed the feat/credential-hot-reload branch from 0b76bd0 to c2684ce Compare September 24, 2026 15:06
@lalan7

lalan7 commented Sep 24, 2026

Copy link
Copy Markdown
Contributor Author

/retest

@blublinsky

Copy link
Copy Markdown
Contributor

/lgtm
/approve

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Sep 24, 2026
@openshift-ci

openshift-ci Bot commented Sep 24, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: blublinsky

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Sep 24, 2026
@openshift-merge-bot

Copy link
Copy Markdown
Contributor

/retest-required

Remaining retests: 0 against base HEAD e537fb5 and 2 for PR HEAD c2684ce in total

@lalan7

lalan7 commented Sep 24, 2026

Copy link
Copy Markdown
Contributor Author

/retest

@red-hat-konflux

Copy link
Copy Markdown
Contributor

All PipelineRuns for this commit have already succeeded. Use /retest <pipeline-name> to re-run a specific pipeline or /test to re-run all pipelines.

@lalan7
lalan7 force-pushed the feat/credential-hot-reload branch from c2684ce to 8b73200 Compare September 25, 2026 15:51
@openshift-ci openshift-ci Bot removed the lgtm Indicates that a PR is ready to be merged. label Sep 25, 2026
@lalan7

lalan7 commented Sep 25, 2026

Copy link
Copy Markdown
Contributor Author

/retest

1 similar comment
@lalan7

lalan7 commented Sep 25, 2026

Copy link
Copy Markdown
Contributor Author

/retest

@red-hat-konflux

Copy link
Copy Markdown
Contributor

All PipelineRuns for this commit have already succeeded. Use /retest <pipeline-name> to re-run a specific pipeline or /test to re-run all pipelines.

@blublinsky

Copy link
Copy Markdown
Contributor

/retest

@red-hat-konflux

Copy link
Copy Markdown
Contributor

All PipelineRuns for this commit have already succeeded. Use /retest <pipeline-name> to re-run a specific pipeline or /test to re-run all pipelines.

@blublinsky

Copy link
Copy Markdown
Contributor

/test "Red Hat Konflux / bundle-e2e-tests / ols-bundle"

@blublinsky

Copy link
Copy Markdown
Contributor

/test

…LLM secret rotation

When credentialHotReload is enabled on the OLSConfig CR, the operator
removes the watcher annotation from LLM provider secrets so that
secret data changes no longer trigger rolling restarts. The flag is
propagated to the service via the olsconfig.yaml ConfigMap, where the
service re-reads credential files from disk on every LLM request.

Changes:
- api/v1alpha1: add CredentialHotReload *bool field to OLSConfig CRD
- olsconfig_helpers: remove watcher annotation from LLM secrets when
  flag is enabled, re-annotate when disabled
- appserver/assets: propagate credential_hot_reload into olsconfig.yaml
- watchers: remove old watcher-filter skip logic
- e2e: add test verifying annotation removal, ConfigMap propagation,
  and annotation restoration on disable
- docs: add credential-hot-reload design and operations guide
- bundle: update CRD manifest with new field

Ref: https://issues.redhat.com/browse/RFE-9380
@lalan7
lalan7 force-pushed the feat/credential-hot-reload branch from 8b73200 to a2027cc Compare September 29, 2026 18:05
@lalan7

lalan7 commented Sep 29, 2026

Copy link
Copy Markdown
Contributor Author

/retest

@blublinsky

Copy link
Copy Markdown
Contributor

/override "Red Hat Konflux / operator-e2e-tests-direct / lightspeed-operator"
/lgtm

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Sep 30, 2026
@openshift-ci

openshift-ci Bot commented Sep 30, 2026

Copy link
Copy Markdown
Contributor

@blublinsky: Overrode contexts on behalf of blublinsky: Red Hat Konflux / operator-e2e-tests-direct / lightspeed-operator

Details

In response to this:

/override "Red Hat Konflux / operator-e2e-tests-direct / lightspeed-operator"
/lgtm

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@openshift-ci

openshift-ci Bot commented Sep 30, 2026

Copy link
Copy Markdown
Contributor

@lalan7: all tests passed!

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@openshift-merge-bot
openshift-merge-bot Bot merged commit cca6a4a into openshift:main Sep 30, 2026
18 of 19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. lgtm Indicates that a PR is ready to be merged.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants